<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台（PHP版）
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | gitee下载：https://gitee.com/likeshop_gitee/likeadmin
// | github下载：https://github.com/likeshop-github/likeadmin
// | 访问官网：https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------


namespace app\common\service\pay;


use app\api\service\RecycleReportService;
use app\common\enum\PayEnum;
use app\common\model\buy\EgoldCountLog;
use app\common\model\buy\EgoldLog;
use app\common\model\Config;
use app\common\model\order\Order;
use app\common\model\user\User;
use app\common\model\user\UserAuth;
use app\lib\MessageBus\base\AmqpBus;
use app\lib\MessageBus\BusEnum;
use Yansongda\Pay\Pay;
use think\facade\Db;
use think\facade\Log;


/**
 * 微信支付
 * Class WeChatPayService
 * @package app\common\server
 */
class PayService extends BasePayService
{
    /**
     * 授权信息
     * @var UserAuth|array|\think\Model
     */
    protected $auth;


    /**
     * 微信配置
     * @var
     */
    protected $config;


    /**
     * easyWeChat实例
     * @var
     */
    protected $app;


    /**
     * 当前使用客户端
     * @var
     */
    protected $terminal;

    static protected function payconfig(){
        $config = config('pay')??null;
        return $config;
    }
    /**
     * @notes 发起微信支付统一下单
     * @param $from
     * @param $order
     * @return array|false|string
     * @author 段誉
     * @date 2021/8/4 15:05
     */
    public static function pay($option)
    {
        try {
            switch ($option['paytype']) {
                case PayEnum::WECHAT_PAY:
                    Pay::config(self::payconfig());
                    $order = [
                        'out_trade_no' => $option['out_trade_no'],
                        'description' => $option['description'],
                        'amount' => [
                            'total' => $option['money']*100,
                        ],
                        'scene_info' => [
                            'payer_client_ip' => $option['client_ip'],
                            'h5_info' => [
                                'type' => 'Wap',
                            ]
                        ],
                    ];
                    $data = Pay::wechat()->wap($order)->toArray();
                    break;
                case PayEnum::ALI_PAY:
                    Pay::config(self::payconfig());
                    $result = Pay::alipay()->app([
                        'out_trade_no' => $option['out_trade_no'],
                        'total_amount' => $option['money'],
                        'subject' => $option['description'],
                        '_config' => 'default',
                    ]);
                    $h5_url = $result->getBody()->getContents();
                    $data['h5_url'] = $h5_url;
                    break;
                default:
                    self::$error = '订单异常';
                    $result = false;
            }
            return $data;
        } catch (\Exception $e) {
            return false;
        }
    }
    public static function notify($paytype=2){
        if($paytype==2){
            Log::write('微信回调开始');
            Pay::config(self::payconfig());
            $result = Pay::wechat()->callback();
            Log::write('订单支付回调信息打印: '.json_encode($result).' ------');
            $out_trade_no = $result['resource']['ciphertext']['out_trade_no']??null;
            $transaction_id = $result['resource']['ciphertext']['transaction_id']??null;
            if (!$out_trade_no)return false;
            $order = self::getOrder($out_trade_no);
            if ($order->isEmpty())return false;
            if (!$order = self::processOrder($order,$transaction_id))return false;
            self::recharge($order);
            $response = Pay::wechat()->success();
        }elseif($paytype==3){
            Pay::config(self::payconfig());
            $result = Pay::alipay()->callback();
            Log::write('支付宝订单支付回调信息打印: '.json_encode($result).' ------');
            $out_trade_no = $result['out_trade_no']??null;
            $transaction_id = $result['trade_no']??null;
            if (!$out_trade_no)return false;
            $order = self::getOrder($out_trade_no);
            if ($order->isEmpty())return false;
            if (!$order = self::processOrder($order,$transaction_id))return false;
            self::recharge($order);
            $response = Pay::alipay()->success();
        }
        return $response;
    }
    /*
     * 充值过程
     * */
    public static function recharge($order) {
        Log::write('【充值】订单信息' . json_encode($order), 'info');
        $user_data = [];
        switch ($order['type']) {
            //书币充值
            case 1:
                if ($order['egold']>0){
                    //增加书币记录
                    self::egoldlog($order['user_id'],1,'充值',$order['egold']);
                }
                if ($order['zb']>0){
                    //增加赠币币记录
                    self::egoldlog($order['user_id'],2,'充值赠送',$order['zb']);
                }
                $user_data = [
                    'paynum'	  => Db::raw('paynum+1'),
                    'egold'	      => Db::raw('egold+'.$order['egold']),
//                    'zb'	      => Db::raw('zb+'.$order['zb']),
                    'paymoney'	  => Db::raw('paymoney+'.$order['money'])
                ];
                break;
            case 5:
                // 季卡充值
                $viptime = User::where('id='.$order['user_id'])->value('vip_enddate');
                if($viptime>time()){
                    $user_time = date('Y-m-d',$viptime);
                }else{
                    $user_time = date('Y-m-d');
                }
                $end = strtotime('+3 months', strtotime($user_time));
                $user_data = ['is_vip'=>1,'vip_enddate'=>$end,'paymoney'=>Db::raw('paymoney+'.$order['money'])];
                break;
            case 6:
                // 年卡充值
                $viptime = User::where('id='.$order['user_id'])->value('vip_enddate');
                if($viptime>time()){
                    $user_time = date('Y-m-d',$viptime);
                }else{
                    $user_time = date('Y-m-d');
                }
                $end = strtotime('+1 year', strtotime($user_time));
                $user_data = ['is_vip'=>1,'vip_enddate'=>$end,'paymoney'=>Db::raw('paymoney+'.$order['money'])];
                break;
            case 7:
                // 活动充值
                if ($order['egold']>0){
                    //增加书币记录
                    self::egoldlog($order['user_id'],1,'充值',$order['egold']);
                }
                if ($order['zb']>0){
                    //增加赠币币记录
                    self::egoldlog($order['user_id'],2,'充值赠送',$order['zb']);
                }
                $user_data = [
                    'paynum'	  => Db::raw('paynum+1'),
                    'egold'	      => Db::raw('egold+'.$order['egold']),
//                    'zb'	      => Db::raw('zb+'.$order['zb']),
                    'paymoney'	  => Db::raw('paymoney+'.$order['money'])
                ];
                break;
        }
        User::where('id',$order['user_id'])->update($user_data);
        AmqpBus::instance()->publish(
            [
                "order_id"=>$order->id,
                "bus_name"=>BusEnum::ORDER_RETURN
            ]
        );
    }

    public static function egoldlog($user_id,$type,$title,$egold) {
        $time = time();
        $period_of_validity = Config::where('name','period_of_validity')->value('value')??7;//获取后台配置的过期天数
        $expire_time = strtotime(date('Y-m-d', strtotime('+' . $period_of_validity . ' day')));
        $log['user_id'] =$user_id;
        $log['type'] =$type;
        $log['title'] =$title;
        $log['egold'] =$egold;
        $log['create_time'] =$time;
        $log['update_time'] =$time;
        if ($type==2){
            $log['expire_time'] = $expire_time;
        }
        $egoldLogId = EgoldLog::EgoldLogQuery($user_id)->insertGetId($log);
        if ($type==2){
            $data = [
                'user_id'=>$user_id,
                'egold'=>$egold,
                'egold_log_id'=>$egoldLogId,
                'create_time'=>$time,
                'expire_time'=>$expire_time,
                'delete_time'=>0,
            ];
            EgoldCountLog::EgoldCountLogQuery($user_id)->insert($data);
        }
    }

    public static function processOrder($order, $transaction_id)
    {
        // 进行核心业务处理, 如更新状态, 发送通知等等
        // 处理成功, 返回true, 处理失败, 返回false
        // 例如:
            $order->transaction_id = $transaction_id;
            $order->status = 1;
            $order->update_time = time();
            $order->pay_time = time();
            $order->save();
            return $order;

    }

    // 去本地服务器查询订单信息
    public static function getOrder($out_trade_no) {
        // 可根据商户订单号进行查询
        $order = Order::where('out_trade_no',$out_trade_no)->where('status',0)->findOrEmpty();
        return $order;
    }
}
